package com.softgroup.breath.easyecgproject.myapi;

import android.util.Log;

/**
 * Created by Administrator on 2017/9/19.
 */

public class HeartRateCount {
    private float avgHeartRate;
    private int maxHeartRate;
    private int minHeartRate;
    private int realTimeHeartRate;
    private int sub = 1;
    private int sub1 = 0;
    private byte[] hrs;
    private float[] finalData;
    private float hhData[];
    private float bigData[];
    private float toOneData[];

    public HeartRateCount() {
    }


    public int getAvgHeartRate() {
        return Math.round(avgHeartRate);
    }

    public int getMaxHeartRate() {
        return maxHeartRate;
    }

    public int getMinHeartRate() {
        return minHeartRate;
    }

    public int getRealTimeHeartRate() {
        return realTimeHeartRate;
    }

    public void initHeartRateCount() {
        avgHeartRate = 0;
        maxHeartRate = 0;
        minHeartRate = 0;
        realTimeHeartRate = 0;
        sub = 1;
        hrs = new byte[10];
    }

    public void getHeartRate(float[] ecgData, int len, boolean hPass) {
        sub1++;
        float hr = 0;
        if (sub1 % 16 == 0) {
            hr = hrv(ecgData, len, hPass);
        }
        if (sub < 300) {
            if (hr != 0) {
                avgHeartRate = (avgHeartRate * (sub - 1) + hr) / sub;
                sub++;
            }
        } else if ((hr - avgHeartRate) * (hr - avgHeartRate) < 900) {
            avgHeartRate = (avgHeartRate * (sub - 1) + hr) / sub;
            sub++;
        }
        if (minHeartRate == 0) {
            minHeartRate = (int) hr;
        } else if (minHeartRate > hr & (hr - avgHeartRate) * (hr - avgHeartRate) < 2500) {
            minHeartRate = (int) hr;
        }
        if (maxHeartRate < hr & (hr - avgHeartRate) * (hr - avgHeartRate) < 2500) {
            maxHeartRate = (int) hr;
        }
        if ((hr - avgHeartRate) * (hr - avgHeartRate) < 2500) {
            if (sub1 % 16 == 0) {
                realTimeHeartRate = (int) hr;
            }
        }
        if (sub1 / 16 < 10) {
            hrs[sub1 / 16] = (byte) realTimeHeartRate;
        }

    }

    public void initSub1() {
        sub1 = 0;
    }

    private float hrv(float[] ecgData, int len, boolean hPass) {
        int[] HRR = new int[200];
        float hr = 0;
        float avgHighPass = 0f;
        float varHighPass = 0f;
        float sumHighPass = 0f;
        float sumVarHighPass = 0f;
        float[] hcurdata = new float[len];
        float[] CChcurdata = new float[len];
        float a = 0.58f;
        float varVpt = 0.003f;
        float max = 0f;
        float min = 0f;
        float normalizing = 1f;
        hhData = new float[len];
        toOneData=new float[len];
        if (len > 0) {
            if (!hPass)//gaotong
            {
                hcurdata = ecgData.clone();
            } else //wei gaotong
            {
                hcurdata[0] = ecgData[0];
                hhData[0] = hcurdata[0];
                for (int i = 1; i < len; i++) {
                    //高通
                    hcurdata[i] = a * hcurdata[i - 1] + a * (ecgData[i] - ecgData[i - 1]);
                    hhData[i] = hcurdata[i];
                    //两点平滑
                    if (i > 1) {
                        hcurdata[i - 1] = (hcurdata[i - 2] + 2 * hcurdata[i - 1] + hcurdata[i]) / 4;
//                        Log.e("max-min", hcurdata[i-1]+"");
                    }
                    sumHighPass += hcurdata[i - 1];
                    if (max == 0f) {
                        max = hcurdata[i-1];
                    } else if (hcurdata[i-1] > max) {
                        max = hcurdata[i-1];
                    }
                    if (min == 0f) {
                        min = hcurdata[i-1];
                    } else if (min > hcurdata[i-1]) {
                        min = hcurdata[i-1];
                    }
                }
                sumHighPass += hcurdata[len - 1];
                finalData = hcurdata.clone();
                normalizing = 0.7f / (max - min);//归一系数
//                Log.e("max-min", max + ">" + min + ">" + (max - min));
                avgHighPass = sumHighPass * normalizing / len;
                for (int i = 0; i < len; i++) {
                    sumVarHighPass += (hcurdata[i] * normalizing - 0) * (hcurdata[i] * normalizing - 0);
                }
                varHighPass = sumVarHighPass / len;
                //信号质量
//                Log.e("data_quality", varHighPass + "");
                for (int i = 0; i < len; i++) {
                    hcurdata[i] = normalizing * hcurdata[i];
                    toOneData[i]=hcurdata[i];
                }
                if (varHighPass > 0.3 * varVpt & varHighPass < 3 * varVpt) {

                    //放大系数
                    for (int i = 2; i < len - 2; i++) {
                        CChcurdata[i] = 10000 * hcurdata[i] * hcurdata[i] * (hcurdata[i + 2] - hcurdata[i]) * (hcurdata[i] - hcurdata[i - 2]);
                        if (CChcurdata[i] > -0.1) {
                            CChcurdata[i] = 0;
                        }

                    }
                    bigData = CChcurdata.clone();
                    int z = 0;
                    //R波
                    for (int i = 4; i < len - 2; i++) {
                        if (((CChcurdata[i] - CChcurdata[i - 2]) < 0) & ((CChcurdata[i] - CChcurdata[i - 1]) < 0) & ((CChcurdata[i] - CChcurdata[i + 1]) < 0) & ((CChcurdata[i] - CChcurdata[i + 2]) < 0)) {

                            HRR[z] = i;
//                            R波高度控制
//                            Log.e("hr_", CChcurdata[i] + ">>><<<" + i);
                            if (CChcurdata[i] < -400 | CChcurdata[i] > -15) {
                                continue;
                            }
                            if (z > 0) {
                                if ((HRR[z] - HRR[z - 1]) < 27) {
                                    continue;
                                }
                            }
                            //                            相邻RR间期控制
                            if (z > 2) {
                                if (!isSmooth(HRR[z - 2] - HRR[z - 3], HRR[z - 1] - HRR[z - 2], HRR[z] - HRR[z - 1])) {
                                    return hr;
                                }
                            }
                            z = z + 1;
                        }
                    }
                    if (z > 1) {
                        hr = 6000 * (z - 1) / (HRR[z - 1] - HRR[0]);
                    }
                }
            }
        }
        if (hr > 50 & hr < 220) {
            return hr;
        } else {
            return 0;
        }
    }

    private boolean isSmooth(float v1, float v2, float v3) {
        if (v1 < (v2 + v3) / 2 * 0.2 | v1 > (v2 + v3) / 2 * 1.2) {
            return false;
        }
        if (v2 < (v1 + v3) / 2 * 0.2 | v2 > (v1 + v3) / 2 * 1.2) {
            return false;
        }
        if (v3 < (v2 + v1) / 2 * 0.2 | v3 > (v2 + v1) / 2 * 1.2) {
            return false;
        }
        return true;
    }

    public  byte[] getHrs() {
        return hrs;
    }

    public float[] getFinalData() {
        return finalData;
    }

    public float[] getHhData() {
        return hhData;
    }

    public float[] getBigData() {
        return bigData;
    }

    public float[] getToOneData() {
        return toOneData;
    }
}
